package com.tomtop.core.redis.config;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

import com.tomtop.core.redis.ByteRedisTemplate;
import com.tomtop.core.redis.EnableTransactionIntegerRedisTemplate;
import com.tomtop.core.redis.IntegerRedisTemplate;
import com.tomtop.core.redis.JsonBytesRedisTemplate;
import com.tomtop.core.redis.LongRedisTemplate;
import com.tomtop.core.redis.RedisTemplatePackage;

import redis.clients.jedis.JedisPoolConfig;

@Configuration
@EnableCaching
public class RedisConfig {

	static Logger log = LoggerFactory.getLogger(RedisConfig.class);

	@Bean
	@ConfigurationProperties("spring.redis.pool")
	JedisPoolConfig poolConfig(JedisConnectionFactory factory) {
		return factory.getPoolConfig();
	}

	@Bean
	Map<Integer, RedisTemplatePackage> redisTemplatePackages(JedisConnectionFactory factory) {
		Map<Integer, RedisTemplatePackage> map = new HashMap<>();
		for (int index = 0; index < 16; index++) {
			JedisConnectionFactory targetFactory = new JedisConnectionFactory();
			BeanUtils.copyProperties(factory, targetFactory);
			targetFactory.setDatabase(index);
			map.put(index, new RedisTemplatePackage(targetFactory));
		}
		return map;
	}

	@Bean
	RedisTemplatePackage redisTemplatePackage(Map<Integer, RedisTemplatePackage> redisTemplatePackages,
			JedisConnectionFactory factory) {
		int dbIndex = factory.getDatabase();
		return redisTemplatePackages.get(dbIndex);
	}

	@Bean
	StringRedisTemplate stringRedisTemplate(RedisTemplatePackage redisTemplatePackage) {
		return redisTemplatePackage.getStringRedisTemplate();
	}

	@Bean
	@Primary
	RedisTemplate<String, Object> redisTemplate(RedisTemplatePackage redisTemplatePackage) {
		return redisTemplatePackage.getRedisTemplate();
	}

	@Bean
	IntegerRedisTemplate integerRedisTemplate(RedisTemplatePackage redisTemplatePackage) {
		return redisTemplatePackage.getIntegerRedisTemplate();
	}

	@Bean
	LongRedisTemplate longRedisTemplate(RedisTemplatePackage redisTemplatePackage) {
		return redisTemplatePackage.getLongRedisTemplate();
	}

	@Bean
	EnableTransactionIntegerRedisTemplate enableTransactionIntegerRedisTemplate(
			RedisTemplatePackage redisTemplatePackage) {
		return redisTemplatePackage.getEnableTransactionIntegerRedisTemplate();
	}

	@Bean
	ByteRedisTemplate byteRedisTemplate(RedisTemplatePackage redisTemplatePackage) {
		return redisTemplatePackage.getByteRedisTemplate();
	}

	@Bean
	JsonBytesRedisTemplate jsonBytesRedisTemplate(RedisTemplatePackage redisTemplatePackage) {
		return redisTemplatePackage.getJsonBytesRedisTemplate();
	}

	@Bean
	@Primary
	@ConfigurationProperties(prefix = "spring.redis.expire")
	CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {
		return new RedisCacheManager(redisTemplate);
	}
}
